package org.jeecg.modules.demo.safemanage.zyhazardinvestigation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.entity.ZyHazardInvestigation;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.entity.ZyRectificationInformation;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.entity.ZyReviewInformation;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.mapper.ZyHazardInvestigationMapper;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.mapper.ZyRectificationInformationMapper;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.mapper.ZyReviewInformationMapper;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.service.IZyHazardInvestigationService;
import org.jeecg.modules.demo.safemanage.zyhazardinvestigation.vo.ZyHazardInvestigationFinishStatusVo;
import org.jeecg.modules.demo.zyHazardInvestigationFather.entity.ZyHazardInvestigationFather;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 中阳隐患排查信息
 * @Author: jeecg-boot
 * @Date:   2024-03-20
 * @Version: V1.0
 */
@Service
@Slf4j
public class ZyHazardInvestigationServiceImpl extends ServiceImpl<ZyHazardInvestigationMapper, ZyHazardInvestigation> implements IZyHazardInvestigationService {

	@Autowired
	private ZyHazardInvestigationMapper zyHazardInvestigationMapper;
	@Autowired
	private ZyRectificationInformationMapper zyRectificationInformationMapper;
	@Autowired
	private ZyReviewInformationMapper zyReviewInformationMapper;

	@Autowired
	private ISysBaseAPI sysBaseAPI;

	@Autowired
	private ISysUserService sysUserService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveMain(ZyHazardInvestigation zyHazardInvestigation, List<ZyRectificationInformation> zyRectificationInformationList,List<ZyReviewInformation> zyReviewInformationList) {
		zyHazardInvestigationMapper.insert(zyHazardInvestigation);
		ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		 获取id，为了到发送超时提醒的时候查询记录
		String id = zyHazardInvestigation.getId();
		Date deadline = zyHazardInvestigation.getRectificationDeadline();
		long delay = deadline.getTime() - System.currentTimeMillis();

		ScheduledFuture<?> future = scheduler.schedule(() -> {
			// 在给定日期后执行的推送信息操作
			ZyHazardInvestigation zyHazardInvestigation1 = zyHazardInvestigationMapper.selectById(id);
			String result = zyHazardInvestigation1.getResult();
			String rectifierPerson = zyHazardInvestigation1.getRectifierPerson();
			SysUser sysUser = sysUserService.lambdaQuery().eq(SysUser::getRealname, rectifierPerson).one();

			if ("待整改".equals(result)){
				// 发送超时提醒
				System.out.println("发送超时提醒");
				LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
				MessageDTO message = new MessageDTO(loginUser.getUsername(),sysUser.getUsername(),"发送超时提醒","任务已超时，请及时处理");
				sysBaseAPI.sendSysAnnouncement(message);
				log.info("发送成功");
			}
		}, delay, TimeUnit.MILLISECONDS);
		scheduler.shutdown();
		if(zyRectificationInformationList!=null && zyRectificationInformationList.size()>0) {
			for(ZyRectificationInformation entity:zyRectificationInformationList) {
				//外键设置
				entity.setParentId(zyHazardInvestigation.getId());
				entity.setStatus(zyHazardInvestigation.getRectifierStatus());
				zyRectificationInformationMapper.insert(entity);
			}
		}
		if(zyReviewInformationList!=null && zyReviewInformationList.size()>0) {
			for(ZyReviewInformation entity:zyReviewInformationList) {
				//外键设置
				entity.setParentId(zyHazardInvestigation.getId());
				entity.setStatus(zyHazardInvestigation.getReviewerStatus());
				zyReviewInformationMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateMain(ZyHazardInvestigation zyHazardInvestigation,List<ZyRectificationInformation> zyRectificationInformationList,List<ZyReviewInformation> zyReviewInformationList) {
		zyHazardInvestigationMapper.updateById(zyHazardInvestigation);
		
		//1.先删除子表数据
//		zyRectificationInformationMapper.deleteByMainId(zyHazardInvestigation.getId());
		zyReviewInformationMapper.deleteByMainId(zyHazardInvestigation.getId());

		List<ZyRectificationInformation> riRecodes = zyRectificationInformationMapper.selectByMainId(zyHazardInvestigation.getId());

		//2.子表数据重新插入
		if(zyRectificationInformationList!=null && zyRectificationInformationList.size()>0) {
			for(ZyRectificationInformation entity:zyRectificationInformationList) {
				//外键设置
				entity.setParentId(zyHazardInvestigation.getId());
				if (riRecodes.size() == 0){
					zyRectificationInformationMapper.insert(entity);
				}else {
					LambdaQueryWrapper<ZyRectificationInformation> updatewrapper = new LambdaQueryWrapper<>();
					updatewrapper.eq(ZyRectificationInformation::getParentId, zyHazardInvestigation.getId());
					zyRectificationInformationMapper.update(entity,updatewrapper);
				}
			}
		}
		if(zyReviewInformationList!=null && zyReviewInformationList.size()>0) {
			for(ZyReviewInformation entity:zyReviewInformationList) {
				//外键设置
				entity.setParentId(zyHazardInvestigation.getId());
				zyReviewInformationMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delMain(String id) {
		zyRectificationInformationMapper.deleteByMainId(id);
		zyReviewInformationMapper.deleteByMainId(id);
		zyHazardInvestigationMapper.deleteById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			zyRectificationInformationMapper.deleteByMainId(id.toString());
			zyReviewInformationMapper.deleteByMainId(id.toString());
			zyHazardInvestigationMapper.deleteById(id);
		}
	}

    @Override
    public List<ZyHazardInvestigationFinishStatusVo> getFinishStatusVoList(String startDate, String endDate,String siteId) {
        List<ZyHazardInvestigationFinishStatusVo> dailyCorrectionStatusCount = zyHazardInvestigationMapper.getDailyCorrectionStatusCount(startDate, endDate,siteId);
        return dailyCorrectionStatusCount;
    }
	public List<ZyHazardInvestigationFinishStatusVo> getWeeklyFinishStatusVoList(String startDate, String endDate, String siteId) {
		Map<String, Object> params = new HashMap<>();
		params.put("startDate", startDate);
		params.put("endDate", endDate);
		params.put("siteId", siteId);
		return zyHazardInvestigationMapper.getWeeklyCorrectionStatusCount(params);
	}
	public List<ZyHazardInvestigationFinishStatusVo> getMonthlyFinishStatusVoList(String startDate, String endDate, String siteId) {
		Map<String, Object> params = new HashMap<>();
		params.put("startDate", startDate);
		params.put("endDate", endDate);
		params.put("siteId", siteId);
		return zyHazardInvestigationMapper.getMonthlyCorrectionStatusCount(params);
	}

	@Override
	public byte[] generateExcelBytes(List<ZyHazardInvestigation> exportList, ZyHazardInvestigationFather father) {
		try (Workbook workbook = new XSSFWorkbook()) {
			Sheet sheet = workbook.createSheet("导出记录");
			// 设置默认行高和列宽
			sheet.setDefaultRowHeightInPoints(20); // 设置默认行高
			sheet.setDefaultColumnWidth(15); // 设置默认列宽
			// 创建样式
			CellStyle headerStyle = createHeaderStyle(workbook);
			CellStyle dataStyle = createDataStyle(workbook);
			Row titleRow = sheet.createRow(0);
			titleRow.setHeightInPoints(45); // 标题行高
			CellRangeAddress titleMerge = new CellRangeAddress(0, 0, 0, 7); // 合并0-8列（共8列）
			sheet.addMergedRegion(titleMerge);
			Cell titleCell = titleRow.createCell(0);
			String name = father.getName();
			titleCell.setCellValue(name + "整改监督信息");
			// 标题样式
			CellStyle titleStyle = workbook.createCellStyle();
			Font titleFont = workbook.createFont();
			titleFont.setBold(true);
			titleFont.setFontHeightInPoints((short) 16); // 字体大小
			titleStyle.setFont(titleFont);
			titleStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中
			titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
			titleCell.setCellStyle(titleStyle);

			//3.3 第三行：四个清单标签（居中加粗，带边框）
			Row listRow = sheet.createRow(1);
			listRow.setHeightInPoints(25); // 清单行高
			// 问题清单（合并0-2列）
			CellRangeAddress problemMerge = new CellRangeAddress(1, 1, 0, 3);
			sheet.addMergedRegion(problemMerge);
			Cell problemCell = listRow.createCell(0);
			problemCell.setCellValue("问题清单");
			// 任务清单（合并2-4列）
			CellRangeAddress taskMerge = new CellRangeAddress(1, 1, 4,6);
			sheet.addMergedRegion(taskMerge);
			Cell taskCell = listRow.createCell(3);
			taskCell.setCellValue("任务清单");
			// 责任清单（）
			Cell responsibilityCell =listRow.createCell(7);
			responsibilityCell.setCellValue("责任清单");
			// 清单样式（居中、加粗、带边框）
			CellStyle listStyle = workbook.createCellStyle();
			Font listFont = workbook.createFont();
			listFont.setBold(true);
			listStyle.setFont(listFont);
			listStyle.setAlignment(HorizontalAlignment.CENTER);
			listStyle.setVerticalAlignment(VerticalAlignment.CENTER);
			// 边框设置（模拟表格线）
			listStyle.setBorderTop(BorderStyle.THIN);
			listStyle.setBorderBottom(BorderStyle.THIN);
			listStyle.setBorderLeft(BorderStyle.THIN);
			listStyle.setBorderRight(BorderStyle.THIN);
			// 应用样式到四个清单单元格
			problemCell.setCellStyle(listStyle);
			taskCell.setCellStyle(listStyle);
			responsibilityCell.setCellStyle(listStyle);

			// 应用样式到四个清单单元格
			// 问题清单（0-2列）
			for (int i = 0; i <= 3; i++) {
				Cell cell = listRow.getCell(i);
				if (cell == null) {
					cell = listRow.createCell(i);
				}
				cell.setCellStyle(listStyle);
			}

			// 任务清单（4-6列）
			for (int i = 4; i <= 6; i++) {
				Cell cell = listRow.getCell(i);
				if (cell == null) {
					cell = listRow.createCell(i);
				}
				cell.setCellStyle(listStyle);
			}

			// 责任清单（6列）
			for (int i = 7; i <= 7; i++) {
				Cell cell = listRow.getCell(i);
				if (cell == null) {
					cell = listRow.createCell(i);
				}
				cell.setCellStyle(listStyle);
			}


			// 创建表头行
			Row headerRow = sheet.createRow(2);
			headerRow.setHeightInPoints(25); // 设置表头行高
			String[] headers = {"是否以前年度发现问题","问题分类", "集团内部巡视通报共性问题", "举一反三自查问题", "整改措施","完成时限","落实进展情况","责任部门"};
			// 设置列宽（与表头数组对应）
			sheet.setColumnWidth(0, 30 * 256);
			sheet.setColumnWidth(1, 15 * 256);
			sheet.setColumnWidth(2, 30 * 256);
			sheet.setColumnWidth(3, 30 * 256);
			sheet.setColumnWidth(4, 50 * 256);
			sheet.setColumnWidth(5, 15 * 256);
			sheet.setColumnWidth(6, 30 * 256);
			sheet.setColumnWidth(7, 15 * 256);
			for (int i = 0; i < headers.length; i++) {
				Cell cell = headerRow.createCell(i);
				cell.setCellValue(headers[i]);
				cell.setCellStyle(headerStyle);
			}

			// 填充数据行
			int rowNum = 3;
			for (ZyHazardInvestigation zyHazardInvestigation: exportList) {
				Row row = sheet.createRow(rowNum++);
				//将时间转化为特定格式
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
				String dateStr = sdf.format(zyHazardInvestigation.getRectificationDeadline());
				setCellValue(row, 0, zyHazardInvestigation.getFlag(), dataStyle);
				setCellValue(row, 1, zyHazardInvestigation.getQualityType(), dataStyle);
				setCellValue(row, 2, zyHazardInvestigation.getCommonProblem(), dataStyle);
				setCellValue(row, 3, zyHazardInvestigation.getProblemDescription(), dataStyle);
				setCellValue(row, 4, zyHazardInvestigation.getMeasure(), dataStyle);
				setCellValue(row, 5, dateStr, dataStyle);
				setCellValue(row, 6, zyHazardInvestigation.getProgress(), dataStyle);
				setCellValue(row, 7, zyHazardInvestigation.getDepartment(), dataStyle);
			}
			//对所有列应用合并逻辑
			mergeSameCells(sheet, 0);
			mergeSameCells(sheet, 1);
			mergeSameCells(sheet, 2);
			mergeSameCells(sheet, 3);
			mergeSameCells(sheet, 4);
			mergeSameCells(sheet, 5);
			mergeSameCells(sheet, 6);
			mergeSameCells(sheet, 7);

//			mergeSameCells(sheet, 1);
//			mergeSameCells(sheet, 2);
//			mergeSameCells(sheet, 3);


//            // 智能列宽调整（新增的核心优化）
//            for (int i = 0; i < headers.length; i++) {
//                sheet.autoSizeColumn(i);
//                int currentWidth = sheet.getColumnWidth(i);
//
//                // 动态计算新宽度（中文适配）
//                int newWidth = Math.min(Math.max(
//                        (int)(currentWidth * 1.2) + 512, // 增加20%宽度+额外缓冲
//                        10 * 256                         // 最小宽度10字符
//                ), 100 * 256);                       // 最大宽度限制100字符
//
//                sheet.setColumnWidth(i, newWidth);
//            }

			// 将Excel写入字节数组（关键修改）
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			workbook.write(baos);
			return baos.toByteArray(); // 返回字节数组
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public int countByFocusQualityType(String qualityType) {
		return baseMapper.countByFocusQualityType(qualityType);
	}


	// 创建优化的表头样式
	static CellStyle createHeaderStyle(Workbook workbook) {
		CellStyle style = workbook.createCellStyle();
		// 设置背景色
		style.setFillForegroundColor(IndexedColors.WHITE.getIndex());
		style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		// 设置边框
		style.setBorderBottom(BorderStyle.THIN);
		style.setBorderTop(BorderStyle.THIN);
		style.setBorderLeft(BorderStyle.THIN);
		style.setBorderRight(BorderStyle.THIN);
		// 设置字体
		Font font = workbook.createFont();
		font.setBold(true);
		font.setFontHeightInPoints((short) 12);
		font.setFontName("宋体"); // 使用宋体显示中文
		style.setFont(font);
		// 居中对齐
		style.setAlignment(HorizontalAlignment.CENTER);
		style.setVerticalAlignment(VerticalAlignment.CENTER);
		// 自动换行
		style.setWrapText(true);
		return style;
	}

	// 创建数据行样式
	static CellStyle createDataStyle(Workbook workbook) {
		CellStyle style = workbook.createCellStyle();

		// 设置边框
		style.setBorderBottom(BorderStyle.THIN);
		style.setBorderTop(BorderStyle.THIN);
		style.setBorderLeft(BorderStyle.THIN);
		style.setBorderRight(BorderStyle.THIN);

		// 设置自动换行
		style.setWrapText(true);

		// 垂直居中
		style.setVerticalAlignment(VerticalAlignment.TOP); // 顶部对齐更美观

		return style;
	}

//	// 设置单元格值并应用样式
//	static void setCellValue(Row row, int columnIndex, String value, CellStyle style) {
//		if (row == null) return;
//
//		Cell cell = row.createCell(columnIndex);
//		cell.setCellValue(value);
//		if (style != null) {
//			cell.setCellStyle(style);
//		}
//
//		// 特别处理长文本内容，自动调整行高
//		if ( value != null && value.length() > 0) {
//			row.setHeightInPoints(calculateRowHeight(value+18));
//		}
//	}

	static void setCellValue(Row row, int columnIndex, String value, CellStyle style) {
		if (row == null) return;

		Cell cell = row.createCell(columnIndex);
		cell.setCellValue(value != null ? value : ""); // 防止null值

		// 创建新的样式，确保居中对齐
		CellStyle newStyle = row.getSheet().getWorkbook().createCellStyle();
		if (style != null) {
			newStyle.cloneStyleFrom(style);
		}

		// 设置水平和垂直居中
		newStyle.setAlignment(HorizontalAlignment.CENTER);
		newStyle.setVerticalAlignment(VerticalAlignment.CENTER);

		cell.setCellStyle(newStyle);

		// 特别处理长文本内容，自动调整行高
		if (value != null && value.length() > 0) {
			row.setHeightInPoints(calculateRowHeight(value));
		}
	}


	// 计算行高（根据文本长度）
	private static float calculateRowHeight(String text) {
		int lineCount = (int) Math.ceil(text.length() / 20.0); // 每80字符为一行
		return Math.max(100, 15 * lineCount); // 最小行高50，每行增加15
	}

	// 合并相同列的连续相同单元格
	static void mergeSameCells(Sheet sheet, int columnIndex) {
		int startRow = 3; // 数据从第3行开始（索引2）
		int lastRow = sheet.getLastRowNum();
		if (lastRow <= startRow) return;
		for (int i = startRow + 1; i <= lastRow; i++) {
			// 获取当前行和上一行对象
			Row currentRow = sheet.getRow(i);
			Row previousRow = sheet.getRow(i - 1);
			if (currentRow == null || previousRow == null) continue;
			Cell currentCell = currentRow.getCell(columnIndex);
			Cell previousCell = previousRow.getCell(columnIndex);
			String currentValue = getCellValueAsString(currentCell);
			String previousValue = getCellValueAsString(previousCell);
			if (!currentValue.equals(previousValue)) {
				if (i - 1 > startRow) {
					sheet.addMergedRegion(new CellRangeAddress(startRow, i - 1, columnIndex, columnIndex));
					// 合并后居中显示
					centerMergedCells(sheet, startRow, i - 1, columnIndex);
				}
				startRow = i;
			} else if (i == lastRow) {
				sheet.addMergedRegion(new CellRangeAddress(startRow, i, columnIndex, columnIndex));
				// 合并后居中显示
				centerMergedCells(sheet, startRow, i, columnIndex);
			}
		}
	}

	// 获取单元格值
	private static String getCellValueAsString(Cell cell) {
		if (cell == null) {
			return "";
		}

		switch (cell.getCellType()) {
			case STRING:
				return cell.getStringCellValue();
			case NUMERIC:
				if (DateUtil.isCellDateFormatted(cell)) {
					return cell.getDateCellValue().toString();
				} else {
					return String.valueOf(cell.getNumericCellValue());
				}
			case BOOLEAN:
				return String.valueOf(cell.getBooleanCellValue());
			case FORMULA:
				return cell.getCellFormula();
			case BLANK:
				return "";
			default:
				return "";
		}
	}

	// 合并后单元格垂直居中
	private static void centerMergedCells(Sheet sheet, int firstRow, int lastRow, int column) {
		Row firstRowObj = sheet.getRow(firstRow);
		if (firstRowObj == null) return;

		Cell firstCellObj = firstRowObj.getCell(column);
		if (firstCellObj == null) return;

		CellStyle originalStyle = firstCellObj.getCellStyle();
		CellStyle style = sheet.getWorkbook().createCellStyle();
		style.cloneStyleFrom(originalStyle);
		style.setVerticalAlignment(VerticalAlignment.CENTER);

		for (int i = firstRow; i <= lastRow; i++) {
			Row row = sheet.getRow(i);
			if (row != null) {
				Cell cell = row.getCell(column);
				if (cell != null) {
					cell.setCellStyle(style);
				}
			}
		}
	}


}
